package com.yequan.leetcode.array.trap_42;

/**
 * //给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。
 * //
 * //
 * //
 * // 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图，在这种情况下，可以接 6 个单位的雨水（蓝色部分表示雨水）。 感谢 Mar
 * //cos 贡献此图。
 * //
 * // 示例:
 * //
 * // 输入: [0,1,0,2,1,0,1,3,2,1,2,1]
 * //输出: 6
 * // Related Topics 栈 数组 双指针
 *
 * @author : Administrator
 * @date : 2020/4/4
 */
public class Trap {

    public static void main(String[] args) {
        int[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
        Trap trap = new Trap();
        int res = trap.trap2(height);
        System.out.println(res);
    }

    /**
     * 暴力法
     * 1.遍历数组,每个位置数组的存水量为:
     * 从当前位置往左扫描,获取左侧最大高度maxLeft
     * 从当前位置往右扫描,获取右侧最大高度maxRight
     * 则当前存水量为 min(maxLeft,maxRight)-height[当前位置]
     * 将所有位置存水量累加
     *
     * @param height
     * @return
     */
    public int trap1(int[] height) {
        if (null == height) {
            return 0;
        }
        int res = 0;
        for (int i = 1; i < height.length; i++) {
            int maxLeft = 0;
            int maxRight = 0;
            for (int j = 0; j <= i; j++) {
                maxLeft = Math.max(maxLeft, height[j]);
            }
            for (int j = i; j < height.length; j++) {
                maxRight = Math.max(maxRight, height[j]);
            }
            res += Math.min(maxLeft, maxRight) - height[i];
        }
        return res;
    }

    /**
     * 双指针法:
     * 对暴力法的优化: 将左右的最大高度存储起来,同时从数组两端进行扫描
     *
     * @param height
     * @return
     */
    public int trap2(int[] height) {
        int res = 0, maxLeft = 0, maxRight = 0, left = 0, right = height.length - 1;
        while (left <= right) {
            maxLeft = Math.max(maxLeft, height[left]);
            maxRight = Math.max(maxRight, height[right]);
            if (maxLeft <= maxRight) {
                res += maxLeft - height[left++];
            } else {
                res += maxRight - height[right--];
            }
        }
        return res;
    }

}
